package com.znjc.device.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.znjc.common.constant.DeviceConstants;
import com.znjc.device.domain.DeviceBoard;
import com.znjc.device.domain.DeviceCommand;
import com.znjc.device.domain.vo.HardwareData;
import com.znjc.device.mapper.DeviceCommandMapper;
import com.znjc.device.service.IDeviceBoardService;
import com.znjc.device.service.IDeviceCommandRefService;
import com.znjc.device.service.IDeviceCommandService;
import com.znjc.device.util.DataUtil;
import com.znjc.device.websocket.WebSocketUsers;
import com.znjc.system.service.ISysDictDataService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author zengpc
 * @date 2023-12-04
 */
@Service
public class DeviceCommandServiceImpl extends ServiceImpl<DeviceCommandMapper, DeviceCommand> implements IDeviceCommandService {

    @Resource
    IDeviceCommandRefService deviceCommandRefService;
    @Resource
    ISysDictDataService sysDictDataService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private IDeviceBoardService deviceBoardService;

    @Override
    public List<DeviceCommand> getCommandList(Long typeId, Integer tag) {
        List<Long> commandIds = deviceCommandRefService.getIdList(typeId);
        if (CollectionUtils.isEmpty(commandIds)) {
            return null;
        }
        LambdaQueryWrapper<DeviceCommand> wrapper = new LambdaQueryWrapper();
        wrapper.in(DeviceCommand::getId, commandIds);
        if (null != tag) {
            wrapper.eq(DeviceCommand::getCommandType, tag);
        }
        return this.list(wrapper);
    }

    @Override
    public void analyzeData(JSONObject data) {
        String clientId = data.getString("clientId");
        String clientName = data.getString("clientName");
        Long commandId = data.getLong("commandId");
        String needData = data.getString("needData");
        //硬件配置
        DeviceCommand command = this.getById(commandId);
        if (null != command) {
            if (DeviceConstants.DEVICE_COMMAND_NUMBER.equals(command.getCommandType())) {
                List<String> dataList = DataUtil.packData(needData);
                if (CollectionUtils.isNotEmpty(dataList) && dataList.size() > command.getDataStartBit()) {
                    List<String> dataLength = dataList.subList(2, 4);
                    String bitLenth = dataLength.stream().collect(Collectors.joining());
                    bitLenth = String.valueOf(Integer.parseInt(bitLenth, 16));
                    Integer bitVal = Integer.parseInt(bitLenth);

                    if (bitVal > 0) {
                        List<String> splitList = dataList.subList(command.getDataStartBit() - 1, dataList.size());
                        List<HardwareData> hardwares = new ArrayList<>();
                        HardwareData hardwareData;
                        String value;
                        String name;
                        String itakoCodes;
                        for (int i = 0; i < bitVal; ) {
                            hardwareData = new HardwareData();
                            value = splitList.get(i);
                            //设备类型
                            name = sysDictDataService.selectDictLabel(DeviceConstants.DEVICE_GENRE, value);
                            hardwareData.setName(name);
                            //在线板子数量
                            value = splitList.get(i + 1);
                            Integer num = Integer.parseInt(value);
                            hardwareData.setOnLineItako(num);
                            itakoCodes = "";
                            i = i + 1;
                            for (int j = 1; j <= num; j++) {
                                itakoCodes += splitList.get(i + j) + ",";
                            }
                            if (StringUtils.isNotEmpty(itakoCodes)) {
                                itakoCodes = itakoCodes.substring(0, itakoCodes.length() - 1);
                                hardwareData.setItakoCodes(itakoCodes);
                            }
                            hardwares.add(hardwareData);
                            if("通道转换板".equals(hardwareData.getName()) && hardwareData.getOnLineItako() > 0){
                               packDeviceBoard(hardwareData.getItakoCodes(), clientId);
                            }
                            i = i + num + 1;
                        }
                        //缓存设备类型信息
                        if (CollectionUtils.isNotEmpty(hardwares)) {
                            redisTemplate.opsForValue().set(clientId + "_hardwares", JSONObject.toJSONString(hardwares));

                        }
                    }
                }
            } else {
                //设置命令是否成功
                if (StringUtils.isNotEmpty(needData) && needData.length() > command.getDataStartBit()) {
                    //分割数据
                    List<List<String>> deviceDataList = DataUtil.analysisData(needData, command.getDataStartBit(), command.getDataSplitLen());
                    if (CollectionUtils.isNotEmpty(deviceDataList)) {
                        if (command.getDataBit() < deviceDataList.size()) {
                            List<String> dataList = deviceDataList.get(command.getDataBit() - 1);
                            String realData = dataList.stream().collect(Collectors.joining());
                            if (!command.getDataJudgment().equals(realData)) {
                                WebSocketUsers.sendMessageToUserByText(DeviceConstants.VUE_MSG_CLINET_9999, clientName + "设置命令：" + command.getName() + "失败！");
                            } else {
                                WebSocketUsers.sendMessageToUserByText(DeviceConstants.VUE_MSG_CLINET_9999, clientName + "设置命令：" + command.getName() + "成功！");
                            }
                        }
                    }
                }
            }

        }
    }

    private void packDeviceBoard(String data, String deptId) {
        List<DeviceBoard> boards = new ArrayList<>();
        String[] boardStr = data.split(",");
        DeviceBoard board;
        for (String num : boardStr){
            board = new DeviceBoard();
            board.setBoardCode(num);
            board.setDeptId(Long.parseLong(deptId));
            board.setCreateBy("admin");
            boards.add(board);
        }
        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(boards)) {
            deviceBoardService.saveDeviceBoards(boards);
        }
    }

}
